package com.huanxing.cloud.common.security.component;

import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.security.oauth2.OAuth2ClientProperties;
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

/** oauth2 服务配置 @Author lijx @Date 2022/1/27 13:48 */
@Configuration
@EnableResourceServer
@AllArgsConstructor
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

  private final ResourceServerProperties resourceServerProperties;

  private final OAuth2ClientProperties oAuth2ClientProperties;

  @Bean
  public AuthIgnoreConfig authIgnoreConfig() {
    return new AuthIgnoreConfig();
  }

  @Bean
  @LoadBalanced
  public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
    return restTemplate;
  }

  @Bean
  public ResourceServerTokenServices tokenServices() {
    RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
    DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
    UserAuthenticationConverter userTokenConverter = new CommonUserConverter();
    accessTokenConverter.setUserTokenConverter(userTokenConverter);
    remoteTokenServices.setCheckTokenEndpointUrl(resourceServerProperties.getTokenInfoUri());
    remoteTokenServices.setClientId(oAuth2ClientProperties.getClientId());
    remoteTokenServices.setClientSecret(oAuth2ClientProperties.getClientSecret());
    remoteTokenServices.setRestTemplate(restTemplate());
    remoteTokenServices.setAccessTokenConverter(accessTokenConverter);
    return remoteTokenServices;
  }

  @Override
  public void configure(ResourceServerSecurityConfigurer resources) {
    resources.tokenServices(tokenServices());
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry =
        http.authorizeRequests();
    // 不登录可以访问的接口
    //    permitAllUrlProperties.getReleaseUrls().forEach(url ->
    // registry.antMatchers(url).permitAll());
    authIgnoreConfig().getUrls().forEach(url -> registry.antMatchers(url).permitAll());
    registry.anyRequest().authenticated();
  }
}
